//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#include "eic.h"
#include "CPopBtn.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé est utilisé pour être sûr que les composants créés n'ont
// aucune fonction virtuelle pure.
//

static inline void ValidCtrCheck(CPopupButton *)
{
  new CPopupButton(NULL);
}
//---------------------------------------------------------------------------
class TMyMenuItem : public TMenuItem
{
  public :
    __fastcall TMyMenuItem( TComponent *pOwner) : TMenuItem( Owner) {};

    void __fastcall AdvancedDrawItem(Graphics::TCanvas* ACanvas, const Windows::TRect &ARect, Windows::TOwnerDrawState State, bool TopLevel);
    void __fastcall MyMeasureItem(Graphics::TCanvas* ACanvas, int &Width, int &Height) { TMenuItem::MeasureItem( ACanvas, Width, Height); };
};
//---------------------------------------------------------------------------
__fastcall CPopupButton::CPopupButton(TComponent* Owner)
  : TCustomControl(Owner)
{
  Height            = 25;
  Width             = 100;
  m_nDefaultMenu    = 0;
  m_psbDown         = NULL;
  m_psbButton       = NULL;
  m_paclMenu        = NULL;
  m_bEnabled        = true;
  m_ImagesList      = NULL;
  m_bShowMainText   = true;
  m_bShowBtnDown    = true;
  m_ModalResult     = mrNone;

  m_psbButton           = new TSpeedButton( this);
  m_psbButton->Align    = alClient;
  m_psbButton->Parent   = this;
  m_psbButton->OnClick  = evOnButtonClick;

  m_psbDown             = new TSpeedButton( this);
  m_psbDown->Width      = 15;
  m_psbDown->Align      = alRight;
  m_psbDown->Parent     = this;
  m_psbDown->NumGlyphs  = 2;
  m_psbDown->OnClick    = evOnDownButtonClick;
  m_psbDown->Glyph->LoadFromResourceName(( int)HInstance, "ARROW");

  PopupMenu            = new TPopupMenu( this);
  PopupMenu->AutoPopup = false;
  PopupMenu->OwnerDraw = true;

  m_pMenuItem          = new TMenuItem( this);
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::evOnDownButtonClick( TObject *pSender)
{
  TPoint ptScreen( ClientToScreen( TPoint( 0, Height)));
  if( PopupMenu) PopupMenu->Popup( ptScreen.x, ptScreen.y);
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetActionList( TActionList *paclMenu)
{
  TMenuItem *pItem;

  m_paclMenu = paclMenu;

  PopupMenu->Items->Clear(); // Théoriquement détruit tous les objets TMenuItem
  if( m_paclMenu) {
    for( int i=0; i<m_paclMenu->ActionCount; i++) {
      pItem         = new TMenuItem( PopupMenu);
      pItem->Action = m_paclMenu->Actions[i];
      PopupMenu->Items->Add( pItem);
      if( i==m_nDefaultMenu) {
        pItem->OnDrawItem = DrawItemEvent;
        if (m_ImagesList) {
           // Il faut passer par un bitmap, sinon l'image n'est pas prise en compte
           Graphics::TBitmap *TheBitmap = new Graphics::TBitmap();
           m_ImagesList->GetBitmap(pItem->ImageIndex,TheBitmap);
           m_psbButton->Glyph = TheBitmap;
           delete TheBitmap;
        }
      }

      pItem->OnMeasureItem = MeasureItemEvent;
    }
    if( m_nDefaultMenu>=m_paclMenu->ActionCount) {
      m_psbButton->Action  = NULL;
      m_psbButton->Caption = EmptyStr;
    } else
      m_psbButton->Action  = m_paclMenu->Actions[m_nDefaultMenu];
  } else
    m_psbButton->Action = NULL;

  SetCaption( m_strCaption);

  m_psbButton->OnClick = evOnButtonClick;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetEnabled( bool bEnabled)
{
    m_bEnabled              = bEnabled;
    m_psbDown->Enabled      = m_bEnabled;
    m_psbButton->Enabled    = m_bEnabled;
    TCustomControl::Enabled = m_bEnabled;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetFlat( bool bFlat)
{
  m_psbDown->Flat = bFlat;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetFont( TFont *pfont)
{
  m_psbButton->Font->Assign( pfont);
}
//---------------------------------------------------------------------------
bool __fastcall CPopupButton::GetFlat() const
{
  return m_psbDown->Flat;
}
//---------------------------------------------------------------------------
TFont *__fastcall CPopupButton::GetFont() const
{
  return m_psbButton->Font;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::MeasureItemEvent( TObject *pSender, TCanvas *pCanvas, int &nWidth, int &nHeight)
{
  TMenuItem *pItem = dynamic_cast< TMenuItem*>( pSender); ASSERT( pItem);

  TFontStyles fsSave = pCanvas->Font->Style;
  pCanvas->Font->Style = fsSave << fsBold;
  m_pMenuItem->Caption = pItem->Caption + ( pItem->ShortCut!=scNone ? "\t" + ShortCutToText( pItem->ShortCut) : EmptyStr);
  ((TMyMenuItem*)m_pMenuItem)->MyMeasureItem( pCanvas, nWidth, nHeight);
  pCanvas->Font->Style = fsSave;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::DrawItemEvent( TObject *pSender, TCanvas *pCanvas, const TRect &Rect, bool bSelected)
{
  ASSERT( dynamic_cast< TMenuItem*>( pSender));

  TMyMenuItem *pItem = ( TMyMenuItem*)pSender;

  TFontStyles fsSave = pCanvas->Font->Style;
  pCanvas->Font->Style = fsSave << fsBold;
  TMenuDrawItemEvent evSave = pItem->OnDrawItem;
  pItem->OnDrawItem = NULL;
  pItem->AdvancedDrawItem( pCanvas, Rect, TOwnerDrawState() << ( bSelected ? odSelected : odDefault), false);
  pItem->OnDrawItem = evSave;
  pCanvas->Font->Style = fsSave;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetCaption( const AnsiString strCaption)
{
  m_strCaption = strCaption;

  if( !m_paclMenu) return;
  ASSERT( dynamic_cast< TAction*>( m_paclMenu->Actions[m_nDefaultMenu]));

  if( m_nDefaultMenu<m_paclMenu->ActionCount) {
    m_psbButton->Caption = m_strCaption.IsEmpty() ? (( TAction*)m_paclMenu->Actions[m_nDefaultMenu])->Caption : m_strCaption;
  } else
    m_psbButton->Caption = m_strCaption;

  if( !m_bShowMainText) {
      m_strCaption = "";
      m_psbButton->Caption = "";
  }
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetDefault( int nIndex)
{
  ASSERT( nIndex<m_paclMenu->ActionCount);
  
  m_nDefaultMenu = nIndex;
  SetActionList( m_paclMenu);
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::Notification( TComponent *pComponent, TOperation Operation)
{
  TCustomControl::Notification( pComponent, Operation);
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetImagesList( TCustomImageList *_ImagesList)
{
    m_ImagesList = _ImagesList;
    PopupMenu->Images = m_ImagesList;
    
    if (m_ImagesList && m_paclMenu)
       m_ImagesList->GetBitmap((( TAction*)m_paclMenu->Actions[m_nDefaultMenu])->ImageIndex,m_psbButton->Glyph);
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetShowMainText( bool _bShowMainText)
{
     m_bShowMainText = _bShowMainText;
     SetCaption( (_bShowMainText)?m_strCaption:AnsiString(""));
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetShowBtnDown( bool _bShowBtnDown)
{
     m_bShowBtnDown     = _bShowBtnDown;
     m_psbDown->Visible = m_bShowBtnDown;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::SetFlatBtn( bool bFlat)
{
  m_psbButton->Flat = bFlat;
}
//---------------------------------------------------------------------------
bool __fastcall CPopupButton::GetFlatBtn() const
{
  return m_psbButton->Flat;
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::evOnButtonClick(TObject *Sender)
{
    if (m_paclMenu)
       (( TAction*)m_paclMenu->Actions[m_nDefaultMenu])->Execute();

    TCustomForm *Form = GetParentForm(this);
    if (Form != NULL) {
        Form->ModalResult = m_ModalResult;
    }
}
//---------------------------------------------------------------------------
namespace Cpopbtn
{
  void __fastcall PACKAGE Register()
  {
     TComponentClass classes[1] = {__classid(CPopupButton)};
     RegisterComponents("EIC Ctrlstd", classes, 0);
  }
}
//---------------------------------------------------------------------------
void __fastcall CPopupButton::CMDialogChar(TWMKey &Message)
{
	// Aucune action ne doit doit être déclenchée si le contrôle
	// ou un de ses parents n'est pas visible ou enable.	
	bool bCanfocus = true;
	TWinControl *wcControl = this;
	TCustomForm *cfForm = GetParentForm(this);

	if (cfForm != NULL) {		
		while (wcControl != cfForm) {
			if (!(wcControl->Visible && wcControl->Enabled)) {
				bCanfocus = false;
				break;
			} else {
				wcControl = wcControl->Parent;
			}
		}
	} else {
		bCanfocus = false;
	}

	if ((IsAccel(Message.CharCode, m_psbButton->Caption)) && bCanfocus) {
		m_psbButton->Click();
		Message.Result = 1;	
	}		
}
//---------------------------------------------------------------------------
